package com.ge.boot03web.component;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @BelongsProject: SpringBoot
 * @BelongsPackage: com.ge.boot03web.component
 * @Author: gejingyu
 * @Date: 2024/1/30
 * @Description: yaml的HttpMessageConverter
 */

public class YamlHttpMessageConverter extends AbstractHttpMessageConverter<Object> {

    private ObjectMapper objectMapper = null;

    public YamlHttpMessageConverter() {
        // 调用父项的构造方法，传入新定义的媒体类型，告诉SpringBoot，这个MessageConverter用于处理yaml格式
        super(new MediaType("application", "yaml", StandardCharsets.UTF_8));
        //生成yaml文档的工厂，此项配置为，移除yaml文档开头的---
        YAMLFactory factory = new YAMLFactory()
                .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
        this.objectMapper = new ObjectMapper(factory);
    }

    /**
     * 判断支持哪些类型
     * 此处先不做判断，只要是对象类型都支持
     */
    @Override
    protected boolean supports(Class clazz) {
        return true;
    }

    /**
     * 配合@RequestBody注解，用于将请求中携带的数据转换成指定的对象
     * 此处不需要使用
     */
    @Override
    protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        return null;
    }

    /**
     * 配合@ResponseBody注解，将返回值处理成指定的返回格式
     *
     * @param returnValue   返回值
     * @param outputMessage 响应流
     */
    @Override
    protected void writeInternal(Object returnValue, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {

        // 获取响应流并写入返回值
        // try-with写法，自动关流
        try (OutputStream os = outputMessage.getBody()) {
            this.objectMapper.writeValue(os, returnValue);
        }
    }
}
